/*
 * GUID.java
 *
 * Created on October 4, 2006, 4:29 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.samlam;
import java.util.*;
import java.net.*;
/**
 *
 * @author Sam
 */
public class GUID {
    //Create static variables that can be accessed by all methods
    
   /*lasttime compares to time produced by new construct.
    *if it is the same, an int range (counter) is increased by 1.
    *lasttime is also called by the extractTime() method. 
    */
    private static long lasttime = 0;
    
    private static final int MAX_RANGE = 0xffffff;// highest 6 diget hex.
    private static int range = 0; // instatiates counter
    private static String ip = null; // static so it can be called by extractIP() method.

    //GUID constructor.
    private GUID() {
        
    }
    
    /*generate() method returns 30 digit GUID.  Each GUID will be unique
     *because of a time, location and counter built into the GUID.
     *The time is the system time in milliseconds converted to a hex.
     *If the time of the next GUID produced is the same as the previous, a counter
     *is augmented by 1.  If the counter reaches it's maximum (ffffff) the method
     *will sleep 1 millisecond.
     *The IP address converted to hex makes up the thrid part of the GUID.
     **/
    public static synchronized String generate() throws Exception {
       //Construct new Random variable
        Random rand = new Random();
        // Get the time off of the computer  
        long time = System.currentTimeMillis();
        
        if (range == MAX_RANGE){//begin sleep if loop
        Thread.sleep(1);
        range = 0;
        }// end sleep if
        
        if (time == lasttime)//begin range if
        {
            range = range + 1;//if it is the same, add 1 to range
        }
        else
        {
            range = rand.nextInt(MAX_RANGE);//else create a new random number as range start
        }//end range if

 
        String rangeHex = Long.toHexString(range);//convert counter to hex value
        rangeHex = GUID.pad(6, rangeHex);// pad to 6 digits
        
        
        String timeHex = Long.toHexString(time);//convert time to hex value
        timeHex = GUID.pad(16, timeHex);//
       
        
        InetAddress host = InetAddress.getLocalHost();
       
        ip = host.getHostAddress();
        String delim = ".";
        StringTokenizer st = new StringTokenizer(ip);
        
        String IP1 = st.nextToken(delim);
        String IP2 = st.nextToken(delim);
        String IP3 = st.nextToken(delim);
        String IP4 = st.nextToken(delim);
        
        // convert the 4 elements of IP to Long format
        long IP1Long = Long.parseLong(IP1);
        long IP2Long = Long.parseLong(IP2);
        long IP3Long = Long.parseLong(IP3);
        long IP4Long = Long.parseLong(IP4);
        
        // convert the 4 Longs into Hex format
        String IP1Hex = Long.toHexString(IP1Long);
        IP1Hex = GUID.pad(2,IP1Hex);
        String IP2Hex = Long.toHexString(IP2Long);
        IP2Hex = GUID.pad(2,IP2Hex);
        String IP3Hex = Long.toHexString(IP3Long);
        IP3Hex = GUID.pad(2, IP3Hex);
        String IP4Hex = Long.toHexString(IP4Long);
        IP4Hex = GUID.pad(2,IP4Hex);
        
        String IPHex = IP1Hex + IP2Hex + IP3Hex + IP4Hex;
        
        
        lasttime = time;
        return  timeHex + rangeHex + IPHex;
  }
   
    public static long extractTime(){
        return lasttime;
    }
    public static long extractTime(String g){
        char[] time = new char[16];
        
        for (int i = 0; i < 16 ; i++){
            time[i] = g.charAt(i);
    }
        String timeString = new String(time);
        long timeLong = Long.parseLong(timeString);
        return timeLong;
    }
        
        

    
    public static String extractIP(){
        return ip;
    }
    
    public static int extractCount(){
        return range;
    }
    public static String pad(int pad, String s){
         int digitsIP = pad - s.length();
        
        // add lead 0(s) to Hex for total of 8 digits
        while (digitsIP > 0){
            s = "0" + s;
            digitsIP = digitsIP - 1;
        }
         return s;
    }
    
   
}
